//创建wxrequest类
//通过类的方式封装，让代码更具有可用性
//方便添加新的属性和方法

class WxRequest {
  //设置默认请求参数
  defaults = {
    baseURL: "", //默认基本路径
    url: "", //开发者路径
    data: null,
    header: { "content-type": "application/json" },
    timeout: 60000,
    method: "GET",
    //控制显示load按钮的配置项
    isLoading:true 
  };

  //定义默认请求拦截器和响应拦截器
  interceptors = {
    //设置默认请求拦截器
    request(config) {
      return config;
    },
    response(response) {
      return response;
    },
  };

  //设置一个数组队列
    queue = []


  constructor(params = {}) {
    //将实例里传入的params参数与defaul合并
    //合并基本路径
    this.defaults = Object.assign({}, this.defaults, params);


  }



  request(options = {}) {
    //合并方法里传入的完整请求参数
    //合并完整的url
    options.url = this.defaults.baseURL + options.url;
    //合并配置项
    options = {
      ...this.defaults,
      ...options,
    };
    
    //如果配置项isLoading为true，展示loading框框
    if (this.defaults.isLoading&&!options.method==="UPLOAD") {
          //在发送请求之前展示showloading，同时像数组队列里push一个参数
    //如果为0，就添加标识符request
    //如果timer定时器存在，就清除
    if (this.timerId) {
      clearTimeout(this.timerId)
    }
    //如果当前数组队列里初始没有request，就添加一个,并调用loading
    if (this.queue.length === 0) {
      this.queue.push('request')

      wx.showLoading();
    }
    }
    
    

    //在请求发送前对传入的配置进行处理,调用请求拦截器
    options = this.interceptors.request(options);

    // console.log(options);
    return new Promise((resolve, reject) => {
      //判断传入的配置项是upfile请求还是request请求
      if (options.method==="UPLOAD") {

          console.log('我进入了upload');
          wx.uploadFile({
            ...options,
            //上传成功时
            success:(res)=>{
              //将返回字符串转换为对象
              res.data = JSON.parse(res.data)
              //在响应结果中增加配置信息
              let mergeRes = Object.assign({},res,{config:options,isSuccess:true})
              //传递给拦截器
              mergeRes = this.interceptors.response(mergeRes)
              resolve(mergeRes)
            },
            fail:(err)=>{
              let mergeErr = Object.assign({},err,{config:options,isSuccess:false})
              mergeErr = this.interceptors.response(mergeErr)
              reject(mergeErr)
            }
          })
      }else{
        wx.request({
          ...options,
          success: (result) => {
            //在请求发送后使用响应拦截器对获得的数据进行处理
            //合并返回后的结果和请求参数
            //添加isSuccess的属性判断属性,如果响应成功就为true，失败为false
            let totalres = Object.assign({}, result, {
              config: options,
              isSuccess: true,
            });
            //传递给响应拦截器
            totalres = this.interceptors.response(totalres);
  
            resolve(totalres);
          },
          fail: (err) => {
            //调用接口失败
            //在请求发送后使用响应拦截器对获得的数据进行处理
            //合并返回后的结果和请求参数
            //添加isSuccess的属性判断属性,如果响应成功就为true，失败为false
            let totalerr = Object.assign({}, err, {
              config: options,
              isSuccess: false,
            });
            //传递给响应拦截器
            totalerr = this.interceptors.response(totalerr);
  
            reject(totalerr);
          },
  
          complete: () => {
            //判断不显示loading框框的条件
            if (this.defaults.isLoading&&!options.method==="UPLOAD") {
              
            //在调用接口之后隐藏loading,并且删除传入队列里的request
            this.queue.pop()
            //如果删除后队列里没有request，就追加一个
            if (this.queue.length ===0) {
              this.queue.push('request')
            }
            //同时增加一个定时器，等到最后再删除最后的request
          this.timerId=  setTimeout(()=>{
                  this.queue.pop()
  
                  if (this.queue.length===0) {
                    wx.hideLoading();
                    // console.log('数组里为0 了！');
                  }
  
            },100)
            }
            
          },
        });

      }

    });
  }

  //封装一个upload方法
  /**
   * 
   * @param {*} filePath 文件的地址
   * @param {*} url 服务器的地址
   * @param {*} name 文件名，可从后端读取
   * @param {*} config 后续选填的配置
   */
  upload({filePath,name,url,method="UPLOAD"},config={}){
    // console.log(Object.assign({},{filePath,name,url,method},config));
    //传递进来的upload数据和配置
    console.log(Object.assign({},{filePath,name,url,method},config));
    return this.request(Object.assign({},{filePath,name,url,method},config))
  }

  //封装4个实例方法,请求快捷方法
  get(url, data = {}, config = {}) {
    //设置传入request里的参数
    // console.log(Object.assign({ url, data, method: "GET" }, config),'get');
    return this.request(Object.assign({ url, data, method: "GET" }, config));
  }
  post(url, data = {}, config = {}) {
    //设置传入request里的参数
    return this.request(Object.assign({ url, data, method: "POST" }, config));
  }
  put(url, data = {}, config = {}) {
    //设置传入request里的参数
    return this.request(Object.assign({ url, data, method: "PUT" }, config));
  }
  delete(url, data = {}, config = {}) {
    //设置传入request里的参数
    return this.request(Object.assign({ url, data, method: "DELETE" }, config));
  }

  //封装Promise.all函数
  all(...promise) {
    return Promise.all(promise);
  }
}

export default WxRequest;
